package org.jeecg.modules.uniubi.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.classes.entity.Classes;
import org.jeecg.modules.classes.service.IClassesService;
import org.jeecg.modules.clockRecord.entity.ClockRecord;
import org.jeecg.modules.clockRecord.service.IClockRecordService;
import org.jeecg.modules.employee.entity.Employee;
import org.jeecg.modules.employee.service.IEmployeeService;
import org.jeecg.modules.identificationRecord.entity.IdentificationRecord;
import org.jeecg.modules.identificationRecord.service.IIdentificationRecordService;
import org.jeecg.modules.uniubi.util.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "宇泛1")
@Slf4j
@RestController
@RequestMapping("/uni")
public class UniController {

    @Autowired
    private IIdentificationRecordService identificationRecordService;
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private IClockRecordService clockRecordService;
    @Autowired
    private IClassesService classesService;
    @Autowired
    private HttpClientUtil httpClientUtil;
    @Autowired
    private ApiUtil apiUtil;
    @Value("${uniubi.url}")
    private String path;

    @PostMapping(value = "/callback", consumes = "application/x-www-form-urlencoded")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> callback(@RequestParam Map<String, Object> formData) {
        try {
            JSONObject jsonObject = new JSONObject(formData);
            log.info("宇泛回调参数:{}", jsonObject);
            JSONObject eventMsg = jsonObject.getJSONObject("eventMsg");
            if (eventMsg == null) {
                log.warn("宇泛回调消息体为空");
                return Result.error("Invalid callback data");
            }
            IdentificationRecord identificationRecord = parseIdentificationRecord(eventMsg);
            if (identificationRecord == null) {
                return Result.error("解析记录失败");
            }
            Employee employee = employeeService.getByAdmitGuid(identificationRecord.getAdmitGuid());
            if (employee == null) {
                log.warn("人员未找到: {}", identificationRecord.getAdmitGuid());
                return Result.OK();
            }
            enrichIdentificationRecord(identificationRecord, employee);
            identificationRecordService.save(identificationRecord);
            asyncUpdateClockRecord(identificationRecord);
            return Result.OK();
        } catch (Exception e) {
            log.error("回调方法异常", e);
            return Result.error("Server error");
        }
    }

    // 辅助方法封装
    private IdentificationRecord parseIdentificationRecord(JSONObject eventMsg) {
        try {
            IdentificationRecord record = eventMsg.toJavaObject(IdentificationRecord.class);
            record.setTime(new Date(Long.parseLong(record.getShowTime())));
            return record;
        } catch (Exception e) {
            log.error("回调消息体解析为打卡记录失败", e);
            return null;
        }
    }

    private void enrichIdentificationRecord(IdentificationRecord record, Employee employee) {
        IdentificationRecord lastRecord = identificationRecordService.getLastByAdmitGuid(record.getAdmitGuid());
        int newType = (lastRecord == null || lastRecord.getIdentificationType() == null)
                ? 1
                : (lastRecord.getIdentificationType() == 1 ? 2 : 1);
        record.setIdentificationType(newType).setAdmitName(employee.getName())
                .setDept(employee.getDept()).setClasses(employee.getClasses())
                .setFaceUrl(employee.getFaceUrl())
                .setWorkNumber(employee.getWorkNumber());
        try {
            record.setDate(DateUtils.parseDate(DateUtils.formatDate(record.getTime(), "yyyy-MM-dd"), "yyyy-MM-dd"));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    @Async("asyncExecutor")
    public void asyncUpdateClockRecord(IdentificationRecord identificationRecord) {
        try {
            updateClockRecord(identificationRecord);
        } catch (Exception e) {
            log.error("同步更改打卡记录失败", e);
        }
    }

    // 核心业务逻辑优化
    private void updateClockRecord(IdentificationRecord identificationRecord) {
        Classes todayClasses = classesService.getLastClasses(identificationRecord.getAdmitGuid());
        if (todayClasses == null) {
            log.warn("未找到当天班次: {}", identificationRecord.getAdmitGuid());
            return;
        }
        Date recordTime = identificationRecord.getTime();
        if (todayClasses.getClassesType() == 2) {
            processNightShift(identificationRecord, todayClasses, recordTime);
        } else {
            processDayShift(identificationRecord, todayClasses, recordTime);
        }
    }

    private void processNightShift(IdentificationRecord identificationRecord, Classes classes, Date recordTime) {
        String s = DateUtils.formatDate(recordTime, "yyyy-MM-dd HH:mm:ss");
        String s1 = DateUtils.formatDate(recordTime, "HH:mm:ss");
        if (hasNowExceededHour(12)){//12点之后
            ClockRecord todayByAdmitGuid = clockRecordService.getTodayByAdmitGuid(identificationRecord.getAdmitGuid());
            if (todayByAdmitGuid != null) {
                String inTime = todayByAdmitGuid.getInTime();//今天最早打卡时间
                if (StringUtils.isEmpty(inTime)){
                    String startTime = classes.getStartTime();
                    // 调用方法截取最后10个字符
                    String result = getLastNCharacters(s, 8);
                    if (result.compareTo(startTime) <= 0) {
                        todayByAdmitGuid.setAbnormalType(1).setAbnormal(0);
                    } else {
                        todayByAdmitGuid.setAbnormalType(3).setAbnormal(1);
                    }
                    todayByAdmitGuid.setInTime(s1);
                    todayByAdmitGuid.setInDate(s.substring(0, 10));
                } else {
//                        String endTime = classes.getEndTime();
//                        if (s.compareTo(endTime) < 0) {
//                            todayByAdmitGuid.setAbnormalType(3==todayByAdmitGuid.getAbnormalType() ? 5 : 4).setAbnormal(1);
//                        }
                    todayByAdmitGuid.setOutTime(s1);
                    todayByAdmitGuid.setOutDate(s.substring(0, 10));
                }
                clockRecordService.updateById(todayByAdmitGuid);
            }
        } else {
            ClockRecord yesterdayByAdmitGuid = clockRecordService.getYesterdayByAdmitGuid(identificationRecord.getAdmitGuid());
            if (yesterdayByAdmitGuid != null) {
                yesterdayByAdmitGuid.setOutTime(s1);
                yesterdayByAdmitGuid.setOutDate(s.substring(0, 10));
                clockRecordService.updateById(yesterdayByAdmitGuid);
            } else {
                ClockRecord lastByAdmitGuid = clockRecordService.getLastByAdmitGuid(identificationRecord.getAdmitGuid());
                if (lastByAdmitGuid != null && lastByAdmitGuid.getOutTime() == null){
                    lastByAdmitGuid.setOutTime(s1);
                    lastByAdmitGuid.setOutDate(s.substring(0, 10));
                    clockRecordService.updateById(lastByAdmitGuid);
                }
            }
        }
    }

    private void processDayShift(IdentificationRecord identificationRecord, Classes classes, Date recordTime) {
        ClockRecord todayByAdmitGuid = clockRecordService.getTodayByAdmitGuid(identificationRecord.getAdmitGuid());
        if (todayByAdmitGuid != null) {
            String inTime = todayByAdmitGuid.getInTime();//今天最早打卡时间
            String s = DateUtils.formatDate(recordTime, "HH:mm:ss");
            if (StringUtils.isEmpty(inTime)){
                String startTime = classes.getStartTime();
                // 调用方法截取最后10个字符
                if (s.compareTo(startTime) <= 0) {
                    todayByAdmitGuid.setAbnormalType(1).setAbnormal(0);
                } else {
                    todayByAdmitGuid.setAbnormalType(3).setAbnormal(1);
                }
                todayByAdmitGuid.setInTime(s);
                todayByAdmitGuid.setInDate(DateUtils.formatDate(recordTime, "yyyy-MM-dd"));
            } else {
//                String endTime = classes.getEndTime();
//                if (s.compareTo(endTime) < 0) {
//                    todayByAdmitGuid.setAbnormalType(3==todayByAdmitGuid.getAbnormalType() ? 5 : 4).setAbnormal(1);
//                }
                todayByAdmitGuid.setOutTime(s);
                todayByAdmitGuid.setOutDate(DateUtils.formatDate(recordTime, "yyyy-MM-dd"));
            }
            clockRecordService.updateById(todayByAdmitGuid);
        }
    }

    @AutoLog(value = "人员注册")
    @ApiOperation(value = "人员注册", notes = "人员注册")
    @PostMapping("/add")
    public JSONObject add(@RequestBody Employee employee) {
        String url = path+"/v2/admit/create";
        //对象同名属性赋值
        JSONObject response = httpClientUtil.doPost(url, employee);
        if (response!=null&&response.getBoolean("success")){
            register(response.getJSONObject("data").getString("admitGuid"),employee.getFaceUrl());
            employee.setAdmitGuid(response.getJSONObject("data").getString("admitGuid"));
            employee.setStatus("1");
            employeeService.updateById(employee);
//            apiUtil.authorization(DateUtils.formatDate(employee.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        return response;
    }

    @AutoLog(value = "人像注册")
    @ApiOperation(value = "人像注册",notes = "人像注册")
    @PostMapping("/register")
    public void register(String admitGuid,String faceUrl){
        if(faceUrl!=null){
            String url = path+"/v2/face/register";
            JSONObject params = new JSONObject();
            params.put("admitGuid",admitGuid);
            String s = faceUrl.replaceAll("\\\\", "/");
            String faceUrl1="http://182.92.209.180:39999/jeecg-boot/sys/common/static/"+s;
            params.put("url",faceUrl1);
            JSONObject jsonObject = httpClientUtil.doPost(url, params);
            log.info("response:{}",jsonObject);
        }
    }

    @AutoLog("查询主体")
    @ApiOperation(value = "查询主体",notes = "查询主体")
    @PostMapping("selectOne")
    public void selectOne(Employee employee){
        QueryWrapper<Employee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", employee.getName());
        queryWrapper.eq("id_card_no", employee.getIdCardNo());
        List<Employee> list = employeeService.list(queryWrapper);
        if (list.isEmpty()) {
            return;
        }
        Employee one = list.get(0);
        String url=path+"/v2/admit/detail";
        JSONObject param = new JSONObject();
        param.put("admitGuid", one.getAdmitGuid());
        JSONObject jsonObject = httpClientUtil.doPost(url, param);
        if (jsonObject.getBoolean("success")){
            delete(one.getAdmitGuid());
        }
    }

    @AutoLog(value = "识别主体删除")
    @ApiOperation(value = "识别主体删除",notes = "识别主体删除")
    @PostMapping("/delete")
    public JSONObject delete(String admitGuids){
        String url=path+"/v2/admit/delete";
        HashMap<String, String> param = new HashMap<>();
        param.put("admitGuids",admitGuids);
        return httpClientUtil.doPost(url, param);
    }

    public static String getLastNCharacters(String input, int n) {
        if (input == null || n <= 0) {
            return ""; // 如果输入为空或n无效，返回空字符串
        }
        // 如果字符串长度小于等于n，则直接返回整个字符串
        if (input.length() <= n) {
            return input;
        }
        // 截取最后n个字符
        return input.substring(input.length() - n);
    }

    public boolean hasNowExceededHour(int hour){
        // 获取当前系统时间
        LocalTime currentTime = LocalTime.now();

        // 定义中午12点的时间
        LocalTime noonTime = LocalTime.of(hour, 0);

        // 判断当前时间是否大于12点
        if (currentTime.isAfter(noonTime)) {
            log.info("当前时间大于{}点: {}", hour, currentTime);
            return true;
        } else {
            log.info("当前时间小于或等于{}点: {}", hour, currentTime);
            return false;
        }
    }

}
